package com.tbit.main.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tbit.main.constant.DaoParamConstant;
import com.tbit.main.constant.RedisConstant;
import com.tbit.main.dao.core.BatteryDao;
import com.tbit.main.dao.core.BatteryLoseDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.DateTimeUtil;
import com.tbit.main.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LMY
 * @create 2021-05-27 11:48
 * 电池管理
 */
@Service("batteryService")
public class BatteryServiceImpl implements BatteryService {

    @Autowired
    private BatteryDao batteryDao;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private DataService dataService;
    @Autowired
    private BatteryLoseDao batteryLoseDao;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RoleService roleService;

    @Override
    public List<Battery> getBatteryNOs(List<String> batteryNOs) {
        Map<String, Object> map = new HashMap<>();
        map.put("batterNOs", StringUtil.getStringListString(batteryNOs));
        return batteryDao.getBatteryNOs(map);
    }

    @Override
    public void updateState(List<String> batteryNOs, Integer accountUserId, Integer state) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountUserId", accountUserId);
        map.put("state", state);
        map.put("batteryNOs", StringUtil.getArrayListString(batteryNOs));
        map.put("updateTime", DateTimeUtil.getNowTime());
        batteryDao.updateState(map);

        List<Battery> batteries = getBatteryNOs(batteryNOs);
        for (Battery battery : batteries) {
            redisService.add(RedisConstant.PUSH_BMS_Battery + battery.getBatteryNO(), JSONObject.toJSONString(battery));
        }
    }

    @Override
    public void updateIdState(String batteryNO, String userCode, Integer accountUserId, Integer state, String remark) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountUserId", accountUserId);
        map.put("state", state);
        map.put("batteryId", dataService.getBatteryId(batteryNO));
        map.put("userCode", userCode);
        map.put("updateTime", DateTimeUtil.getNowTime());
        map.put("remark", remark);
        batteryDao.updateIdState(map);

        Battery battery = getByNO(batteryNO);
        redisService.add(RedisConstant.PUSH_BMS_Battery + battery.getBatteryNO(), JSONObject.toJSONString(battery));
    }

    @Override
    public void updateIdStateCode(String batteryNO, String userCode, Integer accountUserId, Integer state) {

        Map<String, Object> map = new HashMap<>();
        map.put("accountUserId", accountUserId);
        map.put("state", state);
        map.put("batteryId", dataService.getBatteryId(batteryNO));
        map.put("updateTime", DateTimeUtil.getNowTime());
        map.put("userCode", userCode);
        if (userCode != null) {
            map.put("machineId", dataService.getMachineIdUserCode(userCode));
        } else {
            map.put("machineId", null);
        }
        batteryDao.updateIdStateCode(map);

        Battery battery = getByNO(batteryNO);
        redisService.add(RedisConstant.PUSH_BMS_Battery + battery.getBatteryNO(), JSONObject.toJSONString(battery));
    }

    @Override
    public void updateIdStateCode(String batteryNO, String userCode, Integer machineId) {
        Map<String, Object> map = new HashMap<>();
        Integer batteryId = dataService.getBatteryIdNoDb(batteryNO);
        if (batteryId == null) {
            return;
        }
        map.put("batteryId", batteryId);
        map.put("userCode", userCode);
        map.put("updateTime", DateTimeUtil.getNowTime());
        map.put("machineId", machineId);
        batteryDao.updateIdStateCode(map);
    }

    @Override
    public Battery getByNO(String batteryNO) {
        Battery battery = batteryDao.getByNO(batteryNO);
        if (battery == null) {
            throw new BaseException("Battery.battery.notNull");
        }
        AccountUser accountUser = dataService.getAccountUser(battery.getAccountUserId());
        if (accountUser != null) {
            battery.setAccountUserName(accountUser.getName());
        }
        return battery;
    }

    @Override
    public List<PowerChangeLogSta> groupByTime(Integer agentId, Integer userType, Integer usermainId, Integer state, String startTime, String endTime) {
        List<PowerChangeLogSta> dlses = new ArrayList<PowerChangeLogSta>();

        /**查询代理商运维账号*/
        List<Integer> accountUserIds = new ArrayList<Integer>();
        /**判断当前账号是不是运维人员*/
        if (roleService.getRoleCode(userType).equals(1)) {
            accountUserIds.add(usermainId);
        }

        Map<String, Object> params = new HashMap<String, Object>();
        params.put(DaoParamConstant.accountId, agentId);
        params.put("accountUserId", StringUtil.getListString(accountUserIds));
        params.put("state", state);
        params.put(DaoParamConstant.startTime, startTime);
        params.put(DaoParamConstant.endTime, endTime);
        dlses = batteryDao.groupByTime(params);

        List<PowerChangeLogSta> dlsefilters = new ArrayList<PowerChangeLogSta>();
        if (dlses.size() > 0) {
            for (PowerChangeLogSta dls : dlses) {
                AccountUser au = accountUserService.getById(dls.getUserMainId());
                if (au != null) {
                    dls.setName(au.getName());
                    dls.setPhone(au.getPhone());
                    dlsefilters.add(dls);
                }
            }
        }

        return dlsefilters;
    }

    @Override
    public List<Battery> getByTime(Integer accountId, Integer userMainId, Integer state, String startTime, String endTime) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(DaoParamConstant.accountId, accountId);
        params.put("accountUserId", userMainId);
        params.put("state", state);
        params.put(DaoParamConstant.startTime, startTime);
        params.put(DaoParamConstant.endTime, endTime);

        return batteryDao.getByTime(params);
    }

    @Override
    public void insert(Battery battery) {
        Battery batteryDB = batteryDao.getByNO(battery.getBatteryNO());
        if (batteryDB != null) {
            throw new BaseException("Battery.batteryNO.exist");
        }
        battery.setAddTime(DateTimeUtil.getNowTime());
        batteryDao.insert(battery);

        Battery batteryDBR = getByNO(battery.getBatteryNO());
        redisService.add(RedisConstant.PUSH_BMS_Battery + batteryDBR.getBatteryNO(), JSONObject.toJSONString(batteryDBR));
    }

    @Override
    public List<Battery> getByAccountId(Integer accountId, Integer state, Integer batteryModelId, Integer pageNO, Integer rowCount) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("state", state);
        map.put("batteryModelId", batteryModelId);
        map.put("rowCount", rowCount);
        map.put("pageNO", (pageNO - 1) * rowCount);
        List<Battery> batteries = batteryDao.getByAccountId(map);

        for (Battery battery : batteries) {
            battery.setBatteryModel(dataService.getByIdBatteryModelChart(battery.getBatteryModelId()).getBatteryModel());
        }
        return batteries;
    }

    @Override
    public Integer getByAccountIdCount(Integer accountId, Integer state, Integer batteryModelId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("state", state);
        map.put("batteryModelId", batteryModelId);
        return batteryDao.getByAccountIdCount(map);
    }

    @Override
    public List<Battery> getByAccountIdReturn(Integer state, Integer accountUserId, Integer accountId) {
        Map<String, Object> map = new HashMap<>();
        map.put("state", state);
        map.put("accountUserId", accountUserId);
        map.put("accountId", accountId);
        return batteryDao.getByAccountIdReturn(map);
    }

    @Override
    public List<Battery> getByAccountIdLose(Integer accountId) {

        List<BatteryLose> batteryLoses = batteryLoseDao.getByAccountId(accountId);
        Map<Integer, BatteryLose> batteryLoseMap = new HashMap<>();
        for (BatteryLose batteryLose : batteryLoses) {
            batteryLoseMap.put(batteryLose.getBatteryId(), batteryLose);
        }

        List<Battery> batteries = batteryDao.getByAccountIdLose(accountId);
        for (Battery battery : batteries) {
            battery.setAccountUserName(dataService.getAccountUser(battery.getAccountUserId()) == null ? null : dataService.getAccountUser(battery.getAccountUserId()).getName());
            battery.setAddAccountUserName(dataService.getAccountUser(battery.getAddAccountUserId()) == null ? null : dataService.getAccountUser(battery.getAddAccountUserId()).getName());
            if (batteryLoseMap.containsKey(battery.getBatteryId())) {
                battery.setUpdateTime(batteryLoseMap.get(battery.getBatteryId()).getLoseTime());
            }
        }

        return batteries;
    }

    @Override
    public Battery getBatteryId(Integer batteryId) {

        Battery battery = batteryDao.getBatteryId(batteryId);
        if (battery == null) {
            throw new BaseException("Battery.battery.notNull");
        }
        battery.setAccountUserName(dataService.getAccountUser(battery.getAccountUserId()) == null ? null : dataService.getAccountUser(battery.getAccountUserId()).getName());

        return battery;
    }

    @Override
    public void del(Integer batteryId) {

        Battery battery = getBatteryId(batteryId);
        redisService.del(RedisConstant.PUSH_BMS_Battery + battery.getBatteryNO());

        batteryDao.del(batteryId);
    }

    @Override
    public List<Battery> getAll() {
        return batteryDao.getAll();
    }

    @Override
    public List<BatteryGroupReturn> stateGroup(Integer accountId) {
        return batteryDao.stateGroup(accountId);
    }

    @Override
    public List<BatteryGroupReturn> userIdGroup(Integer accountId) {
        return batteryDao.userIdGroup(accountId);
    }

    @Override
    public Battery getByUserCode(String userCode) {
        return batteryDao.getByMachineId(dataService.getMachineIdUserCode(userCode));
    }

    @Override
    public List<Battery> getNotGroup(Integer accountId) {

        List<Battery> batteries = batteryDao.getNotGroup(accountId);

        for (Battery battery : batteries) {
            battery.setAccountUserName(dataService.getAccountUser(battery.getAccountUserId()) == null ? null : dataService.getAccountUser(battery.getAccountUserId()).getName());
            battery.setAddAccountUserName(dataService.getAccountUser(battery.getAddAccountUserId()) == null ? null : dataService.getAccountUser(battery.getAddAccountUserId()).getName());
        }

        return batteries;
    }

    @Override
    public Battery getByMachineId(Integer machineId) {
        return batteryDao.getByMachineId(machineId);
    }

    @Override
    public List<Battery> getByMachineIds(List<Integer> machineId) {
        return batteryDao.getByMachineIds(StringUtil.getListString(machineId));
    }

    @Override
    public void auth(List<Agent> agents, Integer batteryId) {
        /**查询设备*/
        Battery battery = batteryDao.getBatteryId(batteryId);

        if (battery == null) {
            throw new BaseException("Battery.battery.notNull");
        }

        /**权限判断*/
        List<Integer> agentIds = new ArrayList<Integer>();
        for (Agent agent : agents) {
            agentIds.add(agent.getAccountId());
        }

        if (!agentIds.contains(battery.getAccountId())) {
            throw new BaseException("System.noPower");
        }
    }
}
